home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / mail / transpor / ifmail23.z / ifmail23 / ifmail / ifcico / yoohoo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-08  |  11.5 KB  |  458 lines

  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include "statetbl.h"
  4. #include "xutil.h"
  5. #include "lutil.h"
  6. #include "ttyio.h"
  7. #include "session.h"
  8. #include "ftscprod.h"
  9. #include "config.h"
  10. #include "ftn.h"
  11. #include "emsi.h"
  12. #include "nodelist.h"
  13.  
  14. #define PRODCODE 0xfe
  15.  
  16. /*------------------------------------------------------------------------*/
  17. /* YOOHOO<tm> CAPABILITY VALUES                                           */
  18. /*------------------------------------------------------------------------*/
  19. #define Y_DIETIFNA 0x0001  /* Can do fast "FTS-0001"  0000 0000 0000 0001 */
  20. #define FTB_USER   0x0002  /* Full-Tilt Boogie        0000 0000 0000 0010 */
  21. #define ZED_ZIPPER 0x0004  /* Does ZModem, 1K blocks  0000 0000 0000 0100 */
  22. #define ZED_ZAPPER 0x0008  /* Can do ZModem variant   0000 0000 0000 1000 */
  23. #define DOES_IANUS 0x0010  /* Can do Janus            0000 0000 0001 0000 */
  24. #define Bit_5      0x0020  /* reserved by FTSC        0000 0000 0010 0000 */
  25. #define Bit_6      0x0040  /* reserved by FTSC        0000 0000 0100 0000 */
  26. #define Bit_7      0x0080  /* reserved by FTSC        0000 0000 1000 0000 */
  27. #define Bit_8      0x0100  /* reserved by FTSC        0000 0001 0000 0000 */
  28. #define Bit_9      0x0200  /* reserved by FTSC        0000 0010 0000 0000 */
  29. #define Bit_a      0x0400  /* reserved by FTSC        0000 0100 0000 0000 */
  30. #define Bit_b      0x0800  /* reserved by FTSC        0000 1000 0000 0000 */
  31. #define Bit_c      0x1000  /* reserved by FTSC        0001 0000 0000 0000 */
  32. #define Bit_d      0x2000  /* reserved by FTSC        0010 0000 0000 0000 */
  33. #define Bit_e      0x4000  /* reserved by FTSC        0100 0000 0000 0000 */
  34. #define WZ_FREQ    0x8000  /* WZ file req. ok         1000 0000 0000 0000 */
  35.  
  36. #define LOCALCAPS (Y_DIETIFNA|ZED_ZIPPER|ZED_ZAPPER)
  37.  
  38. extern unsigned short crc16(char*,int);
  39. extern char *version;
  40. extern int janus(void);
  41. extern int rxwazoo(void);
  42. extern int txwazoo(void);
  43. extern int rxdietifna(void);
  44. extern int txdietifna(void);
  45. extern void rdoptions(node*);
  46. extern int nodelock(faddr*);
  47.  
  48. static int rxyoohoo(void);
  49. static int txyoohoo(void);
  50. static void fillhello(unsigned short,char*);
  51. static void checkhello(void);
  52.  
  53. static int iscaller;
  54. static struct _hello {
  55.     unsigned char data[128];
  56.     unsigned char crc[2];
  57. } hello;
  58.  
  59. int rx_yoohoo(void)
  60. {
  61.     int rc;
  62.     unsigned short capabilities,localcaps;
  63.     char *pwd;
  64.     fa_list *tmp;
  65.     node *nlent;
  66.  
  67.     loginf("start inbound WaZOO session");
  68.  
  69.     pwd=NULL;
  70.     localcaps=LOCALCAPS;
  71.     if (localoptions & NOZMODEM) localcaps &= ~(ZED_ZAPPER|ZED_ZIPPER);
  72.     if (localoptions & NOZEDZAP) localcaps &= ~ZED_ZAPPER;
  73.     if (localoptions & NOJANUS) localcaps &= ~DOES_IANUS;
  74.     emsi_local_opts=0;
  75.     emsi_remote_opts=0;
  76.     iscaller=0;
  77.     if ((rc=rxyoohoo()) == 0)
  78.     {
  79.         checkhello();
  80.         capabilities=hello.data[114]+(hello.data[115]<<8);
  81.         if (capabilities & WZ_FREQ) session_flags |= SESSION_WAZOO;
  82.         else session_flags &= ~SESSION_WAZOO;
  83.         localcaps&=capabilities;
  84.         if (localcaps & DOES_IANUS) localcaps &= DOES_IANUS;
  85.         else if (localcaps & ZED_ZAPPER) localcaps &= ZED_ZAPPER;
  86.         else if (localcaps & ZED_ZIPPER) localcaps &= ZED_ZIPPER;
  87.         else if (localcaps & FTB_USER)   localcaps &= FTB_USER;
  88.         else if (localcaps & Y_DIETIFNA) localcaps &= Y_DIETIFNA;
  89.         if ((localoptions & NOFREQS) == 0) localcaps |= WZ_FREQ;
  90.         else emsi_local_opts |= NRQ;
  91.  
  92.         if (((nlent=getnlent(remote->addr))) &&
  93.             (nlent->pflag != DUMMY))
  94.         {
  95.             loginf("remote is a listed system");
  96.             inbound=listinbound;
  97.             rdoptions(nlent);
  98.         }
  99.  
  100.         for (tmp=pwlist;tmp;tmp=tmp->next)
  101.         if (metric(remote->addr,tmp->addr) == 0)
  102.         {
  103.             if (strncasecmp((char*)hello.data+98,tmp->addr->name,8) != 0)
  104.             {
  105.                 pwd="BAD_PASS";
  106.                 loginf("remote gave password \"%s\", expected \"%s\"",
  107.                     (char*)hello.data+98,tmp->addr->name);
  108.                 localcaps=0;
  109.             }
  110.             else /* password did match, return it back */
  111.             {
  112.                 loginf("remote gave correct password, protected WaZOO session");
  113.                 inbound=protinbound;
  114.                 pwd=tmp->addr->name;
  115.                 break;
  116.             }
  117.         }
  118.  
  119.         fillhello(localcaps,pwd);
  120.  
  121.         rc=txyoohoo();
  122.     }
  123.     if ((rc == 0) && ((localcaps & LOCALCAPS) == 0))
  124.     {
  125.         loginf("No common WaZOO protocols or bad password");
  126.         return 0;
  127.     }
  128.     if (rc) return rc;
  129.     session_flags |= SESSION_WAZOO;
  130.     if (localcaps & DOES_IANUS) return janus();
  131.     else if ((localcaps & ZED_ZAPPER) || (localcaps & ZED_ZIPPER))
  132.     {
  133.         if (localcaps & ZED_ZAPPER) emsi_local_protos=ZAP;
  134.         else emsi_local_protos=ZMO;
  135.         return rxwazoo();
  136.     }
  137.     else if (localcaps & Y_DIETIFNA) return rxdietifna();
  138.     else logerr("WaZOO internal error - no proto for 0x%04xh",localcaps);
  139.     return 1;
  140. }
  141.  
  142. int tx_yoohoo(void)
  143. {
  144.     int rc;
  145.     unsigned short capabilities;
  146.     char *pwd;
  147.     fa_list *tmp;
  148.  
  149.     loginf("start outbound WaZOO session");
  150.  
  151.     pwd=NULL;
  152.     for (tmp=pwlist;tmp;tmp=tmp->next)
  153.     if (metric(remote->addr,tmp->addr) == 0)
  154.     {
  155.         pwd=remote->addr->name;
  156.         break;
  157.     }
  158.     capabilities=LOCALCAPS;
  159.     if (localoptions & NOZMODEM) capabilities &= ~(ZED_ZAPPER|ZED_ZIPPER);
  160.     if (localoptions & NOZEDZAP) capabilities &= ~ZED_ZAPPER;
  161.     if (localoptions & NOJANUS) capabilities &= ~DOES_IANUS;
  162.     if ((localoptions & NOFREQS) == 0) capabilities |= WZ_FREQ;
  163.     else emsi_local_opts |= NRQ;
  164.     fillhello(capabilities,pwd);
  165.     iscaller=1;
  166.     if ((rc=txyoohoo()) == 0)
  167.     {
  168.         rc=rxyoohoo();
  169.         checkhello();
  170.         capabilities=hello.data[114]+(hello.data[115]<<8);
  171.         if (capabilities & WZ_FREQ) session_flags |= SESSION_WAZOO;
  172.         else session_flags &= ~SESSION_WAZOO;
  173.     }
  174.     if ((rc == 0) && ((capabilities & LOCALCAPS) == 0))
  175.     {
  176.         loginf("No common WaZOO protocols");
  177.         return 0;
  178.     }
  179.     if (rc) return rc;
  180.     session_flags |= SESSION_WAZOO;
  181.     if (capabilities & DOES_IANUS) return janus();
  182.     else if ((capabilities & ZED_ZAPPER) || (capabilities & ZED_ZIPPER))
  183.     {
  184.         if (capabilities & ZED_ZAPPER) emsi_local_protos=ZAP;
  185.         else emsi_local_protos=ZMO;
  186.         return txwazoo();
  187.     }
  188.     else if (capabilities & Y_DIETIFNA) return txdietifna();
  189.     else logerr("WaZOO internal error - no proto for 0x%04xh",capabilities);
  190.     return 1;
  191. }
  192.  
  193. SM_DECL(rxyoohoo,"rxyoohoo")
  194. SM_STATES
  195.     sendenq,waitchar,getpacket,sendnak,sendack
  196. SM_NAMES
  197.     "sendenq","waitchar","getpacket","sendnak","sendack"
  198. SM_EDECL
  199.  
  200.     int c;
  201.     int count=0;
  202.     unsigned short lcrc,rcrc;
  203.  
  204. SM_START(sendenq)
  205.  
  206. SM_STATE(sendenq)
  207.  
  208.     if (count++ > 9)
  209.     {
  210.         loginf("too many tries to get hello packet");
  211.         SM_ERROR;
  212.     }
  213.     PUTCHAR(ENQ);
  214.     SM_PROCEED(waitchar)
  215.  
  216. SM_STATE(waitchar)
  217.  
  218.     c=GETCHAR(10);
  219.     if (c == TIMEOUT) {SM_PROCEED(sendenq);}
  220.     else if (c < 0)
  221.     {
  222.         SM_ERROR;
  223.     }
  224.     else switch (c)
  225.     {
  226.     case 0x1f:    SM_PROCEED(getpacket); break;
  227.     case YOOHOO:    SM_PROCEED(sendenq); break;
  228.     default:    debug(10,"got '%s' waiting hello",
  229.                 printablec(c));
  230.             SM_PROCEED(waitchar);
  231.             break;
  232.     }
  233.  
  234. SM_STATE(getpacket)
  235.  
  236.     GET((char*)&hello,sizeof(hello),30);
  237.     if (STATUS)
  238.     {
  239.         SM_ERROR;
  240.     }
  241.     lcrc=crc16((char*)hello.data,sizeof(hello.data));
  242.     rcrc=(hello.crc[0]<<8)+hello.crc[1];
  243.     if (lcrc != rcrc)
  244.     {
  245.         debug(10,"crc does not match in hello packet: %04xh/%04xh",
  246.             rcrc,lcrc);
  247.         SM_PROCEED(sendnak);
  248.     }
  249.     else {SM_PROCEED(sendack);}
  250.  
  251. SM_STATE(sendnak)
  252.  
  253.     if (count++ > 9)
  254.     {
  255.         loginf("too many tries to get hello packet");
  256.         SM_ERROR;
  257.     }
  258.     PUTCHAR('?');
  259.     SM_PROCEED(waitchar);
  260.  
  261. SM_STATE(sendack)
  262.  
  263.     PUTCHAR(ACK);
  264.     SM_SUCCESS;
  265.  
  266. SM_END
  267. SM_RETURN
  268.  
  269.  
  270. SM_DECL(txyoohoo,"txyoohoo")
  271. SM_STATES
  272.     sendyoohoo,waitenq,sendpkt,waitchar
  273. SM_NAMES
  274.     "sendyoohoo","waitenq","sendpkt","waitchar"
  275. SM_EDECL
  276.  
  277.     int c;
  278.     int count=0;
  279.     int startstate;
  280.     unsigned short lcrc;
  281.  
  282.     if (iscaller) startstate=sendpkt;
  283.     else startstate=sendyoohoo;
  284.     lcrc=crc16((char*)hello.data,sizeof(hello.data));
  285.     hello.crc[0]=lcrc>>8;
  286.     hello.crc[1]=lcrc&0xff;
  287.  
  288. SM_START(startstate)
  289.  
  290. SM_STATE(sendyoohoo)
  291.  
  292.     PUTCHAR(YOOHOO);
  293.     SM_PROCEED(waitenq);
  294.  
  295. SM_STATE(waitenq)
  296.  
  297.     c=GETCHAR(10);
  298.     if (c == TIMEOUT)
  299.     {
  300.         if (count++ > 9)
  301.         {
  302.             loginf("timeout waiting ENQ");
  303.             SM_ERROR;
  304.         }
  305.         else
  306.         {
  307.             SM_PROCEED(sendyoohoo);
  308.         }
  309.     }
  310.     else if (c < 0)
  311.     {
  312.         SM_ERROR;
  313.     }
  314.     else switch (c)
  315.     {
  316.     case ENQ:    SM_PROCEED(sendpkt);
  317.     case YOOHOO:    SM_PROCEED(waitenq);
  318.     default:    debug(10,"got '%s' waiting hello ACK",
  319.                 printablec(c));
  320.             SM_PROCEED(waitchar);
  321.             break;
  322.     }
  323.  
  324. SM_STATE(sendpkt)
  325.  
  326.     if (count++ > 9)
  327.     {
  328.         loginf("too many tries to send hello packet");
  329.         SM_ERROR;
  330.     }
  331.  
  332.     PUTCHAR(0x1f);
  333.     PUT((char*)&hello,sizeof(hello));
  334.     if (STATUS) {SM_ERROR;}
  335.     SM_PROCEED(waitchar);
  336.  
  337. SM_STATE(waitchar)
  338.  
  339.     c=GETCHAR(30);
  340.     if (c == TIMEOUT)
  341.     {
  342.         loginf("timeout waiting hello ACK");
  343.         SM_ERROR;
  344.     }
  345.     else if (c < 0)
  346.     {
  347.         SM_ERROR;
  348.     }
  349.     else switch (c)
  350.     {
  351.     case ACK:    SM_SUCCESS; break;
  352.     case '?':    SM_PROCEED(sendpkt); break;
  353.     case ENQ:    SM_PROCEED(sendpkt); break;
  354.     default:    debug(10,"got '%s' waiting hello ACK",
  355.                 printablec(c));
  356.             SM_PROCEED(waitchar);
  357.             break;
  358.     }
  359.  
  360. SM_END
  361. SM_RETURN
  362.  
  363.  
  364. void fillhello(capabilities,password)
  365. unsigned short capabilities;
  366. char *password;
  367. {
  368.     faddr *best;
  369.     unsigned short majver,minver;
  370.  
  371.     debug(10,"fillhello(0x%04hx)",capabilities);
  372.  
  373.     best=bestaka_s(remote->addr);
  374.  
  375.     sscanf(version,"%hd.%hd",&majver,&minver);
  376.     memset(&hello,0,sizeof(hello));
  377.     hello.data[0]='o'; /* signal */
  378.     hello.data[2]=1; /* hello-version */
  379.     hello.data[4]=PRODCODE; /* product */
  380.     hello.data[6]=majver&0xff; /* prod-ver-major */
  381.     hello.data[7]=majver>>8; /* prod-ver-major */
  382.     hello.data[8]=minver&0xff; /* prod-ver-minor */
  383.     hello.data[9]=minver>>8; /* prod-ver-minor */
  384.     strncpy((char*)hello.data+10,name,59); /* name */
  385.     strncpy((char*)hello.data+70,sysop,19); /* sysop */
  386.     hello.data[90]=best->zone&0xff; /* zone */
  387.     hello.data[91]=best->zone>>8; /* zone */
  388.     hello.data[92]=best->net&0xff; /* net */
  389.     hello.data[93]=best->net>>8; /* net */
  390.     hello.data[94]=best->node&0xff; /* node */
  391.     hello.data[95]=best->node>>8; /* node */
  392.     hello.data[96]=best->point&0xff; /* point */
  393.     hello.data[97]=best->point>>8; /* point */
  394.  
  395.     if (password) strncpy((char*)hello.data+98,password,8);
  396.  
  397.     hello.data[114]=capabilities&0xff; /* capabilities */
  398.     hello.data[115]=capabilities>>8; /* capabilities */
  399.     debug(10,"filled hello \"%s\"",printable((char*)hello.data,128));
  400. }
  401.  
  402. void checkhello(void)
  403. {
  404.     unsigned short i,majver,minver;
  405.     fa_list **tmpl,*tmpn;
  406.     faddr remaddr;
  407.     char *prodnm;
  408.  
  409.     if ((hello.data[0] != 'o') ||
  410.         (hello.data[1] != 0) ||
  411.         (hello.data[2] != 1) ||
  412.         (hello.data[3] != 0))
  413.     {
  414.         loginf("got \"%s\" instead of \"o\\000\\001\000\"",
  415.             printable((char*)hello.data,3));
  416.     }
  417.     for (i=0;ftscprod[i].name;i++)
  418.         if (ftscprod[i].code == hello.data[4]) break;
  419.     prodnm=ftscprod[i].name;
  420.     majver=hello.data[6]+(hello.data[7]<<8);
  421.     minver=hello.data[8]+(hello.data[9]<<8);
  422.     remaddr.zone=hello.data[90]+(hello.data[91]<<8);
  423.     remaddr.net=hello.data[92]+(hello.data[93]<<8);
  424.     remaddr.node=hello.data[94]+(hello.data[95]<<8);
  425.     remaddr.point=hello.data[96]+(hello.data[97]<<8);
  426.     remaddr.name=NULL;
  427.     remaddr.domain=NULL;
  428.     for (tmpl=&remote;*tmpl;tmpl=&((*tmpl)->next));
  429.     if (metric(remote->addr,&remaddr) == 0)
  430.     {
  431.         (*tmpl)=(fa_list*)xmalloc(sizeof(fa_list));
  432.         (*tmpl)->next=NULL;
  433.         (*tmpl)->addr=(faddr*)xmalloc(sizeof(faddr));
  434.         (*tmpl)->addr->zone=remaddr.zone;
  435.         (*tmpl)->addr->net=remaddr.net;
  436.         (*tmpl)->addr->node=remaddr.node;
  437.         (*tmpl)->addr->point=remaddr.point;
  438.     }
  439.     for (tmpn=nllist;tmpn;tmpn=tmpn->next)
  440.         if (tmpn->addr->zone == (*tmpl)->addr->zone) break;
  441.     if (tmpn) (*tmpl)->addr->domain=xstrcpy(tmpn->addr->domain);
  442.     else (*tmpl)->addr->domain=NULL;
  443.     (*tmpl)->addr->name=NULL;
  444.  
  445.     for (tmpl=&remote;*tmpl;tmpl=&((*tmpl)->next));
  446.         (void)nodelock((*tmpl)->addr);
  447.         /* lock all remotes, ignore locking result */
  448.  
  449.     loginf("remote  address: %s",ascfnode(remote->addr,0x0f));
  450.     loginf("remote password: %s",(char*)hello.data+98);
  451.     loginf("remote     uses: %s [%02X] version %d.%d",
  452.         prodnm?prodnm:"<unknown program>",hello.data[4],
  453.         majver,minver);
  454.     loginf("remote   system: %s",(char*)hello.data+10);
  455.     loginf("remote operator: %s",(char*)hello.data+70);
  456.     remote->addr->name=xstrcpy((char*)hello.data+70);
  457. }
  458.